package com.atguigu.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.request.AlipayTradeCloseRequest;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeCloseResponse;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.atguigu.config.AlipayConfig;
import com.atguigu.constant.MqConst;
import com.atguigu.entity.OrderInfo;
import com.atguigu.entity.PaymentInfo;
import com.atguigu.enums.PaymentStatus;
import com.atguigu.enums.PaymentType;
import com.atguigu.feign.OrderFeignClient;
import com.atguigu.mapper.PaymentInfoMapper;
import com.atguigu.service.PaymentInfoService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * 支付信息表 服务实现类
 * </p>
 *
 * @author hachimen
 * @since 2021-09-10
 */
@Service
public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, PaymentInfo> implements PaymentInfoService {
    @Autowired
    private AlipayClient alipayClient;
    @Autowired
    private OrderFeignClient orderFeignClient;
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Override
    public String createQrCode(Long orderId) throws Exception {
        /*
         * 1.获取orderInfo
         * 2.保存支付订单信息
         * 3.生成二维码
         * 4.同步请求设置
         * 5.异步请求设置
         * 6.商家信息加入
         */

        OrderInfo orderInfo = orderFeignClient.getOrderInfo(orderId);
        savePaymentInfo(orderInfo);
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(AlipayConfig.return_payment_url);
        alipayRequest.setNotifyUrl(AlipayConfig.notify_payment_url);
        Map<String, Object> requestParamMap = new HashMap<>();
        requestParamMap.put("out_trade_no",orderInfo.getOutTradeNo());
        requestParamMap.put("total_amount",orderInfo.getTotalMoney());
        requestParamMap.put("subject","天气转凉了，需要买个热水袋，希望不要爆炸");
        requestParamMap.put("product_code","FAST_INSTANT_TRADE_PAY");
        alipayRequest.setBizContent(JSON.toJSONString(requestParamMap));
        AlipayTradePagePayResponse response = alipayClient.pageExecute(alipayRequest);
        if(response.isSuccess()){
            return response.getBody();
        }
        return "";
    }

    @Override
    public PaymentInfo getPaymentInfoByOutTradeNo(String outTradeNo) {
        QueryWrapper<PaymentInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("out_trade_no",outTradeNo);
        wrapper.eq("payment_type",PaymentType.ALIPAY.name());
        return baseMapper.selectOne(wrapper);
    }

    @Override
    public void updatePaymentInfo(Map<String, String> paramMap) {
        //获取支付订单信息
        String outTradeNo = paramMap.get("out_trade_no");
        PaymentInfo paymentInfo = getPaymentInfoByOutTradeNo(outTradeNo);
        //修改支付订单状态和信息
        paymentInfo.setPaymentStatus(PaymentStatus.PAID.name());
        paymentInfo.setCallbackTime(new Date());
        paymentInfo.setCallbackContent(paramMap.toString());
        //修改支付订单号并更新
        paymentInfo.setTradeNo(paramMap.get("trade_no"));
        baseMapper.updateById(paymentInfo);
        //发消息修改订单状态
        rabbitTemplate.convertAndSend(MqConst.PAY_ORDER_EXCHANGE,MqConst.PAY_ORDER_ROUTE_KEY,paymentInfo.getOrderId());
    }

    @Override
    public boolean refund(Long orderId) throws AlipayApiException {
        //支付宝退款
        OrderInfo orderInfo = orderFeignClient.getOrderInfo(orderId);
        AlipayTradeRefundRequest alipayRequest = new AlipayTradeRefundRequest();

        Map<String, Object> requestParamMap = new HashMap<>();
        requestParamMap.put("out_trade_no",orderInfo.getOutTradeNo());
        requestParamMap.put("refund_amount",orderInfo.getTotalMoney());
        requestParamMap.put("refund_reason","nmd炸了");
        alipayRequest.setBizContent(JSON.toJSONString(requestParamMap));
        AlipayTradeRefundResponse response = alipayClient.execute(alipayRequest);

        if(response.isSuccess()){
            //成功
            System.out.println("退款成功");
            PaymentInfo paymentInfo = new PaymentInfo();
            paymentInfo.setPaymentStatus(PaymentStatus.ClOSED.name());
            QueryWrapper<PaymentInfo> wrapper = new QueryWrapper<>();
            wrapper.eq("out_trade_no",orderInfo.getOutTradeNo());
            baseMapper.update(paymentInfo,wrapper);
            return true;
        }else {
            //失败
            System.out.println("退款失败");
            return false;
        }
    }

    @Override
    public boolean closeAlipayTrade(Long orderId) throws AlipayApiException {
        //关闭支付宝交易状态
        OrderInfo orderInfo = orderFeignClient.getOrderInfo(orderId);
        AlipayTradeCloseRequest alipayRequest = new AlipayTradeCloseRequest();
        //TODO
        Map<String, Object> requestParamMap = new HashMap<>();
        requestParamMap.put("out_trade_no",orderInfo.getOutTradeNo());
        alipayRequest.setBizContent(JSON.toJSONString(requestParamMap));
        AlipayTradeCloseResponse response = alipayClient.execute(alipayRequest);

        if(response.isSuccess()){
            //成功
            System.out.println("关闭成功");
            return true;
        }else {
            //失败
            System.out.println("关闭失败");
            return false;
        }
    }

    @Override
    public boolean queryAlipayTrade(Long orderId) throws AlipayApiException {
        //查询支付宝订单
        OrderInfo orderInfo = orderFeignClient.getOrderInfo(orderId);
        AlipayTradeQueryRequest alipayRequest = new AlipayTradeQueryRequest();

        Map<String, Object> requestParamMap = new HashMap<>();
        requestParamMap.put("out_trade_no",orderInfo.getOutTradeNo());
        alipayRequest.setBizContent(JSON.toJSONString(requestParamMap));
        AlipayTradeQueryResponse response = alipayClient.execute(alipayRequest);

        if(response.isSuccess()){
            //成功
            System.out.println("订单存在");
            return true;
        }else {
            //失败
            System.out.println("订单不存在");
            return false;
        }
    }

    @Override
    public AlipayTradeQueryResponse queryAlipayTradeStatus(Long orderId) throws AlipayApiException {
        //查询支付宝订单交易状态
        OrderInfo orderInfo = orderFeignClient.getOrderInfo(orderId);
        AlipayTradeQueryRequest alipayRequest = new AlipayTradeQueryRequest();

        Map<String, Object> requestParamMap = new HashMap<>();
        requestParamMap.put("out_trade_no",orderInfo.getOutTradeNo());
        alipayRequest.setBizContent(JSON.toJSONString(requestParamMap));
        AlipayTradeQueryResponse response = alipayClient.execute(alipayRequest);
        return response;
    }

    @Override
    public PaymentInfo getPaymentInfo(String outTradeNo, String paymentType) {
        //获取PaymentInfo
        QueryWrapper<PaymentInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("out_trade_no",outTradeNo);
        wrapper.eq("payment_type",paymentType);
        return baseMapper.selectOne(wrapper);

    }

    @Override
    public void closePaymentInfo(Long orderId) {
        //关闭支付订单
        QueryWrapper<PaymentInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("order_id",orderId);
        PaymentInfo paymentInfo = baseMapper.selectOne(wrapper);
        if(paymentInfo != null){
            paymentInfo.setPaymentStatus(PaymentStatus.ClOSED.name());
            baseMapper.update(paymentInfo,wrapper);
        }
    }

    private void savePaymentInfo(OrderInfo orderInfo) {
        QueryWrapper<PaymentInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("order_id",orderInfo.getId());
        wrapper.eq("payment_type", PaymentType.ALIPAY.name());
        Integer count = baseMapper.selectCount(wrapper);
        if(count>0){
            return;
        }
        PaymentInfo paymentInfo = new PaymentInfo();
        paymentInfo.setOutTradeNo(orderInfo.getOutTradeNo());
        paymentInfo.setOrderId(orderInfo.getId()+"");
        paymentInfo.setPaymentType(PaymentType.ALIPAY.name());
        paymentInfo.setCreateTime(new Date());
        paymentInfo.setPaymentMoney(orderInfo.getTotalMoney());
        paymentInfo.setPaymentContent(orderInfo.getTradeBody());
        paymentInfo.setPaymentStatus(PaymentStatus.UNPAID.name());
        baseMapper.insert(paymentInfo);
    }
}
